-------------------------------------------------
-- 队伍上阵

-- db.combatHero   			上阵信息

-- getTeamType 				根据战斗类型获取出战队伍类型
-- getCombatHeros 			根据出战类型获取出战队伍下标列表
-- getCombatHeroZDL 		根据战斗类型获取出战战力
-- cleanCombatHeros 		清空出战信息
-- updatePos 				设置上阵信息
-------------------------------------------------

local CombatExcel = require("excel.combat")
local HeroExcel = require("excel.hero")
local MonsterExcel = require("excel.monster").monster
local MonsterOutExcel = require("excel.monster").monsterOut
local CombatPosExcel = require("excel.combatPos")
local FormationExcel = CombatPosExcel.formation
local DefineExcel = CombatPosExcel.define[1]
local Util = require("common.Util")
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Broadcast = require("broadcast.Broadcast")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local CombatImpl = require("combat.CombatImpl")
local DrillLogic = require("drill.DrillLogic")
local JjcLogic = require("jjc.JjcLogic")
local UnionWarLogic = require("union.UnionWarLogic")
local UnionLogic = require("union.UnionLogic")
local RoleDefine = require("role.RoleDefine")
local MoshouLogic = require("moshou.MoshouLogic")
local HeroLogic = require("hero.HeroLogic")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local YjTreasureLogic = require("yjTreasure.YjTreasureLogic")
local RoleHeadLogic = require("role.RoleHeadLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local JibanLogic = require("combat.JibanLogic")
local JjcGodWarLogic = require("jjcGodWar.JjcGodWarLogic")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
local ChengjiuDefine = require("chengjiu.ChengjiuDefine")
local SkillExcel = require("excel.skill")
local RoleAttr = require("role.RoleAttr")
local LostTempleCombatLogic = require("lostTemple.lostTempleCombatLogic")

-- 根据战斗类型获取出战队伍类型
function getTeamType(combatType)
    if not CombatExcel.combat[combatType] then return end

	return CombatExcel.combat[combatType].teamType
end

function getCombatHeroDB(human,combatType)
	local teamType = getTeamType(combatType)
	if not human.db.combatHero[teamType] then
		human.db.combatHero[teamType] = {list = {},helpList = {},formation = 1,jiban = {}}
	end
	return human.db.combatHero[teamType],teamType
end

--根据阵法id返回可用站位
function getPosList(formation)
	local formationConf = FormationExcel[formation]
	if not formationConf.posList then
		for k,v in pairs(FormationExcel) do
			v.posList = {}
			for _,v1 in ipairs(v.pos) do
				v.posList[v1] = 1
			end
		end
	end
	return formationConf.posList
end

function getCombatHeros(human, combatType)
	local combatHeroDB = getCombatHeroDB(human,combatType)
	return combatHeroDB.list,combatHeroDB.helpList,combatHeroDB.formation or 1,combatHeroDB
end

-- 清空出战信息
function cleanCombatHeros(human, combatType)
	local teamType = getTeamType(combatType)
	human.db.combatHero[teamType] = nil
end
-- 拷贝上阵
function copyCombatHeros(human, sourceType, targetType)
	local sTeamType = getTeamType(sourceType)
	local tTeamType = getTeamType(targetType)
	if sTeamType == tTeamType then return end

	local combatHeroDB = human.db.combatHero[sTeamType]
	human.db.combatHero[tTeamType] = Util.copyTable(combatHeroDB)
end


-- 可否更新阵容
local function checkUpdatePos(human, msg)
    if msg.type == CombatDefine.COMBAT_TYPE4 then
        if not JjcGodWarLogic.checkCanPos(human) then return end
    end

    if msg.type == CombatDefine.COMBAT_TYPE24 then
    	local moduleFn = CombatLogic.getModule(msg.type)
	    if moduleFn and moduleFn.checkUpdatePos then
	    	return moduleFn.checkUpdatePos(human, msg)
	    end
        return
    end

    local posList = getPosList(msg.formation)
    local heroList = Util.split(msg.heroList, ",")
    local helpList = Util.split(msg.helpList, ",", true)
    local cnt = 0
    local useList = { }
    local fatherList = { }
    -- 确定英雄存不存在
    for i = 1, CombatDefine.COMBAT_HERO_CNT do

        local uuid = heroList[i] or ""
        if uuid ~= "0" and uuid ~= "" then

            if i == CombatDefine.COMBAT_HERO_CNT and canBackup(human) == 0 then
                -- 援军未激活
                return
            end

            if posList[i] == nil and i ~= CombatDefine.COMBAT_HERO_CNT then
                -- 站位不可用
                return
            end

            local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
            if not heroGrid then return end

            local heroConfig = HeroExcel.hero[heroGrid.id]
            if useList[uuid] or fatherList[heroGrid.id] then
                -- 同父类英雄重复
                return
            else
                cnt = cnt + 1
                useList[uuid] = true
                fatherList[heroGrid.id] = true
            end
        end
    end
    if cnt == 0 then
        -- 上阵英雄空
        return
    end
    -- 检查辅助对象是否激活 todo

    return true, heroList, helpList
end

-- 上阵成功处理
function onUpdatePos(human, teamType)
    for combatType, config in pairs(CombatExcel.combat) do
    	if config.teamType == teamType then
    		CombatLogic.onUpdatePos(human, combatType)
    		if combatType == CombatDefine.COMBAT_TYPE1 then
    			ObjHuman.doCalc(human)
	            local heroListZDL = getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
                ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_8,heroListZDL)
    		end
    	end
    end
end

-- 更新上阵信息
function updatePos(human, msg)
	local combatType = msg.type
	local canUpdate,heroList,helpList = checkUpdatePos(human,msg)
	if not canUpdate then
		return
	end
	local combatHeroDB, teamType = getCombatHeroDB(human,combatType)
	combatHeroDB.formation = msg.formation
	combatHeroDB.list = heroList
	combatHeroDB.helpList = helpList
	local msgRet = Msg.gc.GC_COMBAT_POS_UPDATE
	msgRet.type = combatType
    msgRet.teamType = teamType
	Msg.send(msgRet,human.fd)

    if combatType == CombatDefine.COMBAT_TYPE1 then
       HeroLogic.sendBagDots(human)
    end

	RoleHeadLogic.CG_ROLE_COMBATHERO_QUERY(human, msg.type)
	onUpdatePos(human, teamType)
end


-- 设置能否跳过
function setQuick(human, combatType, isQuick)
	local combatConfig = CombatExcel.combat[combatType]
	if combatConfig.isQuick == 1 then
		human.db.combatQuick[combatType] = isQuick
	end	
end
-- 升级检测
function onLvUp(human, oldLv, newLv)
	local heroListZDL = getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE1)
	if heroListZDL <= 0 then return end

	local jjcDenType = CombatDefine.COMBAT_TYPE3
	local jjcGodType = CombatDefine.COMBAT_TYPE4
	local jjcDenLv = RoleSystemLogic.getOpenLv(CombatExcel.combat[jjcDenType].systemID)
	local jjcGodLv = RoleSystemLogic.getOpenLv(CombatExcel.combat[jjcGodType].systemID)

	local change = false
	-- 同步 战役阵容 到 竞技场防守阵容
	if oldLv < jjcDenLv and newLv >= jjcDenLv then
		local heroListJjc = getCombatHeroZDL(human, jjcDenType)
		if heroListJjc <= 0 then
			copyCombatHeros(human, CombatDefine.COMBAT_TYPE1, jjcDenType)
			change = true
		end
		
	end

	-- 同步 战役阵容 到 众神之战/王者争霸
	if oldLv < jjcGodLv and newLv >= jjcGodLv then
		local heroListJjc = getCombatHeroZDL(human, jjcGodType)
		if heroListJjc <= 0 then
			copyCombatHeros(human, CombatDefine.COMBAT_TYPE1, jjcGodType)
			change = true
		end		
	end

	if change  then
		ObjHuman.save(human)
	end
end

-- 获取上阵战力
function getCombatHeroZDL(human, combatType)
	local zhandouli = 0
	local teamType = getTeamType(combatType)
	if teamType then
		local heroList = getCombatHeros(human, combatType)
		if heroList then
			for pos = 1, CombatDefine.COMBAT_HERO_CNT do
				local uuid = heroList[pos]
				local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
 
				if heroGrid and type(heroGrid) == "table" then
                    if human.heroAttrs and not human.heroAttrs[heroGrid.bagIndex] then  
                        RoleAttr.doCalcHero(human, heroGrid.bagIndex)
                    end
					zhandouli = zhandouli + (heroGrid.zhandouli or 0)
				end
			end
		end
	end
	return zhandouli
end

-- 发送阵型信息
FormationInitFlag = nil
function formationQuery(human)
	local msgRet = Msg.gc.GC_COMBAT_FORMATION_QUERY
	if not FormationInitFlag then
		FormationInitFlag = true
		local len = 0
		for k,v in ipairs(FormationExcel) do
			len = len + 1
			local net = msgRet.list[len]
			local len1 = 0
			for k1,v1 in ipairs(v.pos) do
				len1 = len1 + 1
				net.list[len1] = v1
			end
			net.list[0] = len1
			net.id = k
			net.lv = v.lv
			net.icon = v.icon
			net.name = v.name
		end
		msgRet.list[0] = len
	end
	msgRet.lv = human.db.lv
	Msg.send(msgRet,human.fd)
end

-- 去掉所有阵容中的数据
function updateAllPos(human, uuid)
   heroIndexByDelForPos(human, uuid)

   local msgRet = Msg.gc.GC_HERO_UPDATE_ALL_POS
   Msg.send(msgRet,human.fd)
end


-- 英雄被分解 从默认出战中 去除
function heroIndexByDelForPos(human, uuid)
	if not uuid or uuid == "0" or uuid == ""  then return end
	for teamType, combatHero in pairs(human.db.combatHero) do
        if teamType ~= CombatDefine.COMBAT_TYPE10 then
		    local isChange = nil
		    for k, v in pairs(combatHero.list) do
		    	if v == uuid then
		    		combatHero.list[k] = nil
		    		isChange = true
		    	end
		    end
		    if isChange then 
		    	onUpdatePos(human, teamType)
                posQuery(human, teamType)
		    end
        end
	end
end

function caclCampAttr(attr, camp, cnt)
    -- 计算基础属性
	local conf = CombatPosExcel[camp]
	if basicsAttrExcel then
        for _, v in ipairs(conf) do
			if cnt == v.cnt then
				for k1,v1 in ipairs(v.attrs) do
					attr[v1[1]] = attr[v1[1]] or 0
					attr[v1[1]] = attr[v1[1]] + v1[2]
				end
			end
		end
	end
end

PosAttrInitFlag = nil
function posAttrQuery(human)
	local msgRet = Msg.gc.GC_COMBAT_POS_ATTR_QUERY
	if not PosAttrInitFlag then
		PosAttrInitFlag = true
		local len = 0
		for k,v in ipairs(DefineExcel.attrs) do
			len = len + 1
			msgRet.attrs[len].key = v[1]
			msgRet.attrs[len].value = v[2]
		end
		msgRet.attrs[0] = len

		len = 0

		for camp = 1,CombatDefine.CAMP_ALL do
			local conf = CombatPosExcel[camp]
			len = len + 1
			local net = msgRet.list[len]
			net.camp = camp
			net.name = conf[1].name
			local len1 = 0
			for k,v in ipairs(conf) do
				len1 = len1 + 1
				local subNet = net.list[len1]
				subNet.cnt = v.cnt
				local len2 = 0
				for k,v in ipairs(v.attrs) do
					len2 = len2 + 1
					subNet.attrs[len2].key = v[1]
					subNet.attrs[len2].value = v[2]
				end
				subNet.attrs[0] = len2
			end
			net.list[0] = len1
		end
		msgRet.list[0] = len
	end
	Msg.send(msgRet,human.fd)
end

function getPosAttr(objList)
	local campList = {}
	for i = 1,CombatDefine.COMBAT_HERO_CNT do
		local obj = objList[i]
		local config = CombatLogic.getConfigByObj(obj)
		if not config then return end
		campList[config.camp] = campList[config.camp] or 0
		campList[config.camp] = campList[config.camp] + 1
	end
	
	local attr = {}
	for k, v in pairs(campList) do 
	    local camp = k
		local cnt = v
	    caclCampAttr(attr, camp, cnt)
	end
	return attr
end

function onFightBegin(human)
	local attrs1 = human.combat.posAttr[1]
	if attrs1 then
		for k,v in pairs(attrs1) do
			for _,pos in ipairs(CombatDefine.SIDE2POS[CombatDefine.ATTACK_SIDE]) do
				local obj = CombatImpl.objList[pos]
				if obj then
					obj.sysAttr[k] = obj.sysAttr[k] + v
					obj.isSysAttrChange = true
				end
			end
		end
	end
	
	local attrs2 = human.combat.posAttr[2]
	if attrs2 then
		for k, v in pairs(attrs2) do
			for _,pos in ipairs(CombatDefine.SIDE2POS[CombatDefine.DEFEND_SIDE]) do
				local obj = CombatImpl.objList[pos]
				if obj then
					obj.sysAttr[k] = obj.sysAttr[k] + v
					obj.isSysAttrChange = true
				end
			end
		end
	end
end

-- 获得 怪物组的 光环  血量加成
function getCombatHpMaxJiaCheng(monsterOutID)
    local config = MonsterOutExcel[monsterOutID]
    local jobList = {}
    if config and #config.member > 5 then
        for i,member in ipairs(config.member) do
            local monsterID = member[1]
            local monsterConfig = MonsterExcel[monsterID]
            jobList[monsterConfig.job] = jobList[monsterConfig.job] or 0
			jobList[monsterConfig.job] = jobList[monsterConfig.job] + 1
        end
    end

    local attr = {}
	for k, v in pairs(jobList) do 
	    local camp = k
		local cnt = v
		caclCampAttr(attr, camp, cnt)
	end
	
    local buff = 0
    for k, v in pairs(attr) do
        if k == 203 then
            buff = v
            break
        end
    end
    return buff
end

function onLogin(human)	
	posAttrQuery(human)
	formationQuery(human)
    sendAllCombatPos(human)
end

--获得type类型的战斗 上阵的魔兽id  index 是指 冠军试炼场  有三个队列才用
function getCombatMoshou(human,combatType)
	local _,helpList = getCombatHeros(human,combatType)
	return helpList[1]
end

function fontHelpNet(net,type,id,icon)
	net.type = type
	net.id = id or 0
	net.icon = icon or 0
end

function posQuery(human, combatType, group, param, flag)
	local combatConfig = CombatExcel.combat[combatType]
	if not combatConfig then return end
	local msgRet = Msg.gc.GC_COMBAT_POS_QUERY
	local len = 0
	if group and group ~= 0 then
		for k,v in ipairs(CombatExcel.combat) do
			if v.group == group then
				len = len + 1
				msgRet.list[len].type = k
				msgRet.list[len].name = v.name
                msgRet.list[len].isQuickTime = v.isQuickTime
				msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(v.systemID)
			end
		end
	else
		len = len + 1
		msgRet.list[len].type = combatType
		msgRet.list[len].name = combatConfig.name
        msgRet.list[len].isQuickTime = combatConfig.isQuickTime
        msgRet.list[len].needLv = RoleSystemLogic.getOpenLv(combatConfig.systemID)
	end
	msgRet.type = combatType
    msgRet.teamType = combatConfig.teamType
	msgRet.list[0] = len
	local heroList,helpList,formation,combatHeroDB = getCombatHeros(human,combatType)
	local formationConf = FormationExcel[formation]
	msgRet.formation = formation
	len = 0

    local totalZdl = 0
	for i = 1,CombatDefine.COMBAT_HERO_CNT do
		local uuid =  heroList[i] or "0"
        local heroGrid = nil
        if combatType == CombatDefine.COMBAT_TYPE24 then
            heroGrid = LostTempleCombatLogic.getHeroGridByUuid(human, uuid)
        else
            heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
        end
        
		if heroGrid  then
			len = len + 1
			msgRet.heroList[len].pos = i
			msgRet.heroList[len].bagIndex = heroGrid.bagIndex
            msgRet.heroList[len].uuid = heroGrid.uuid

            --重新计算战力 缓存的情况下
            if not heroGrid.isLostTemple then
               if not human.heroAttrs[heroGrid.bagIndex] then  
                  RoleAttr.doCalcHero(human, heroGrid.bagIndex)
               end
            else
               LostTempleCombatLogic.getHeroAttrs(human, heroGrid.bagIndex)
            end

            totalZdl = totalZdl + heroGrid.zhandouli
		end 
	end
    msgRet.totalZdl = totalZdl
	msgRet.heroList[0] = len
	len = 0
	if helpList[1] and helpList[1] > 0 then
		len = len + 1
		MoshouLogic.setPosHelp(msgRet.helpList[len],helpList[1])
	end
	msgRet.helpList[0] = len
    msgRet.backUpLock = canBackup(human)

    local mapID = nil
    if param ~= nil then
       local args = Util.split(param, "|")
       mapID = CombatLogic.getMapID(human, combatType, args)
    end
    msgRet.mapID = mapID or 0
    msgRet.jibanLv = RoleSystemLogic.getOpenLv(RoleSystemDefine.ROLE_SYS_ID_207)
    msgRet.flag = flag or 0
    local cjPrivilege = ChengjiuLogic.checkPrivilege(human, ChengjiuDefine.PRIVILEGE_TYPE_8)
    msgRet.moshouLock = cjPrivilege and 1 or 0
    local skillID = MoshouLogic.getPutMoshouSkillID(human, combatType) or 0
    local skillConfig = SkillExcel.skill[skillID]
    msgRet.moshouSkill = skillConfig and skillConfig.icon or ""
    
	Msg.send(msgRet,human.fd)
end

function canBackup(human)
	local backupDB = human.db.combatBackup or 0
	return backupDB
end

function activeBackup(human)
	human.db.combatBackup = 1
end

function checkPos(formation,pos)
	local ret
	if pos == CombatDefine.COMBAT_BACKUP_POS then
		ret = 1
	else
		local posList = getPosList(formation)
		if posList[pos] then
			ret = 1
		end
	end
	return ret
end

function getFormationConfig(formation)
	return FormationExcel[formation]
end

function sendAllCombatPos(human)
    for k, v in pairs(CombatExcel.combat) do
        posQuery(human, k, v.group)

        JibanLogic.sendQuery(human, k, v.teamType)
    end
end

-- 是否是阵容中最后一个英雄
function isLastInCombat(human,heroIndex)
    if not heroIndex or heroIndex == "" then return end
    local combatTb = Util.copyTable(human.db.combatHero)
	for teamType, combatHero in pairs(combatTb) do
		local isChange = nil
		for k, v in pairs(combatHero.list) do
			if type(v) == "table" then
				for k2, v2 in pairs(v) do
					if v2 == heroIndex then
						v[k2] = nil
						isChange = true
					end
				end
			elseif v == heroIndex then
				combatHero[k] = nil
				isChange = true
			end
		end
		if isChange then 
            local heroCnt = 0
			for k, v in pairs(combatHero) do
		    	if type(v) == "table" then
		    		for k2, v2 in pairs(v) do
		    			if v2 ~= 0 then
		    			    heroCnt = heroCnt + 1
                        end
		    		end
		    	elseif v ~= 0 then
		    		heroCnt = heroCnt + 1
		    	end
		    end
            if heroCnt == 0 then
                return true
            end    
		end
	end
end

local restrict = nil
function getRestrict(attacker,defender,key)
	if not restrict then
		restrict = {}
		for k,v in ipairs(DefineExcel.attrs) do
			restrict[v[1]] = v[2]
		end 
	end
	if restrict[key] and DefineExcel.restrict[attacker.camp] == defender.camp then
		return restrict[key]
	end
	return 0
end

function setCombatByUnionWarGm(human, combatType)
	local heroList = {}
    local cnt = 0
    local useList = { }
    local fatherList = { }
	local helpList = {}
    -- 确定英雄存不存在
    for i = 1, 6 do
		local uuid
		for k, v in pairs(human.db.heroBag) do
			if k and k > 0 and v and v.uuid then
				uuid = v.uuid
				break
			end
		end

		if uuid then
			cnt = cnt + 1
			heroList[cnt] = uuid
		end
    end


	local combatHeroDB, teamType = getCombatHeroDB(human,combatType)
	combatHeroDB.formation = 1
	combatHeroDB.list = heroList
	combatHeroDB.helpList = helpList


end

-- 更新战力
function updateZdl(human, uuidList)
   local list = Util.split(uuidList, "|")

   local msgRet = Msg.gc.GC_HERO_UPDATE_ZDL
   local len = 0
   for i = 1, CombatDefine.COMBAT_HERO_CNT do
      local uuid = list[i]
      if uuid then
         local heroGrid = HeroLogic.getHeroGridByUuid(human, uuid)
         if not heroGrid then return end
         
         if not human.heroAttrs[heroGrid.bagIndex] then 
            RoleAttr.doCalcHero(human, heroGrid.bagIndex)

            len = len + 1
            msgRet.list[len].uuid = uuid
            msgRet.list[len].zdl = heroGrid.zhandouli
         end

      end
   end

   if len > 0 then
      msgRet.list[0] = len
      Msg.send(msgRet,human.fd)
   end
end